// 全局变量
let currentRoomId = null;
let socket = null;
let rsaKeys = {
  privateKey: null,
  publicKey: null
};
let userPublicKeys = {};
let currentUserSid = null;
let isChatEnabled = false;
let messageCount = 0;
let userCount = 0;

// 初始化Socket.IO连接
function initSocket() {
  logToPanel("正在连接服务器...", "info");
  updateStatus("connecting", "连接中...");
  
  socket = io();
  
  socket.on('connect', () => {
    currentUserSid = socket.id;
    logToPanel(`已连接到服务器 (ID: ${getShortId(currentUserSid)})`, "success");
    updateStatus("connected", "已连接");
  });
  
  socket.on('disconnect', () => {
    logToPanel("与服务器断开连接", "warning");
    updateStatus("disconnected", "未连接");
    disableChat();
  });
  
  socket.on('room_created', (data) => {
    currentRoomId = data.room_id;
    document.getElementById('room-id-display').value = currentRoomId;
    logToPanel(`已创建房间: ${currentRoomId}`, "success");
    enableChat();
  });
  
  socket.on('user_joined', (data) => {
    logToPanel(`用户 ${getShortId(data.user_id)} 加入了房间`, "info");
    
    // 更新用户列表
    updateUserList(data.user_list);
    
    // 存储所有用户的公钥
    data.user_list.forEach(user => {
      userPublicKeys[user.sid] = user.public_key;
    });
    
    // 如果是自己加入房间，启用聊天
    if (data.user_id === currentUserSid) {
      enableChat();
    }
    
    // 显示用户加入通知
    displaySystemMessage(`${getShortId(data.user_id)} 加入了房间`);
  });
  
  socket.on('user_left', (data) => {
    logToPanel(`用户 ${getShortId(data.user_id)} 离开了房间`, "warning");
    
    // 从用户列表中移除
    if (userPublicKeys[data.user_id]) {
      delete userPublicKeys[data.user_id];
      updateUserList();
    }
    
    // 显示用户离开通知
    displaySystemMessage(`${getShortId(data.user_id)} 离开了房间`);
  });
  
  socket.on('new_message', async (data) => {
    logToPanel(`收到来自 ${getShortId(data.sender_id)} 的新消息`, "info");
    
    try {
      // 解密消息
      const decrypt = new JSEncrypt();
      decrypt.setPrivateKey(rsaKeys.privateKey);
      const decrypted = decrypt.decrypt(data.encrypted_message);
      
      if (decrypted) {
        // 验证签名
        const senderPublicKey = userPublicKeys[data.sender_id];
        if (senderPublicKey && data.signature) {
          try {
            const verify = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
            verify.init(senderPublicKey);
            verify.updateString(decrypted);
            const isValid = verify.verify(data.signature);
            
            if (isValid) {
              displayMessage(
                data.sender_id === currentUserSid ? '我' : getShortId(data.sender_id), 
                decrypted, 
                data.timestamp, 
                data.sender_id === currentUserSid ? 'me' : 'other'
              );
              logToPanel(`消息签名验证成功`, "success");
            } else {
              logToPanel(`消息签名验证失败，可能消息被篡改`, "error");
              displayMessage(
                data.sender_id === currentUserSid ? '我' : getShortId(data.sender_id), 
                "[签名验证失败] " + decrypted, 
                data.timestamp, 
                data.sender_id === currentUserSid ? 'me' : 'other'
              );
            }
          } catch (e) {
            logToPanel(`签名验证出错: ${e.message}`, "error");
            displayMessage(
              data.sender_id === currentUserSid ? '我' : getShortId(data.sender_id), 
              "[签名验证错误] " + decrypted, 
              data.timestamp, 
              data.sender_id === currentUserSid ? 'me' : 'other'
            );
          }
        } else {
          displayMessage(
            data.sender_id === currentUserSid ? '我' : getShortId(data.sender_id), 
            decrypted, 
            data.timestamp, 
            data.sender_id === currentUserSid ? 'me' : 'other'
          );
        }
      } else {
        logToPanel(`解密来自 ${getShortId(data.sender_id)} 的消息失败`, "error");
      }
    } catch (e) {
      logToPanel(`处理消息时出错: ${e.message}`, "error");
    }
  });
  
  socket.on('error', (data) => {
    logToPanel(`错误: ${data.message}`, "error");
    alert(`错误: ${data.message}`);
  });
}

// 记录日志到面板
function logToPanel(message, type = "info") {
  const logPanel = document.getElementById('log-panel');
  const now = new Date();
  const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
  
  const logEntry = document.createElement('div');
  logEntry.className = 'log-entry';
  
  const timestampSpan = document.createElement('span');
  timestampSpan.className = 'log-timestamp';
  timestampSpan.textContent = `[${timestamp}]`;
  
  const messageSpan = document.createElement('span');
  messageSpan.className = `log-${type}`;
  messageSpan.textContent = message;
  
  logEntry.appendChild(timestampSpan);
  logEntry.appendChild(messageSpan);
  logPanel.appendChild(logEntry);
  
  // 滚动到底部
  logPanel.scrollTop = logPanel.scrollHeight;
}

// 更新连接状态
function updateStatus(status, text) {
  const indicator = document.getElementById('status-indicator');
  const statusText = document.getElementById('connection-status-text');
  const messageStatusText = document.getElementById('message-status-text');
  
  indicator.className = 'status-indicator';
  
  if (status === "connected") {
    indicator.classList.add('status-connected');
    statusText.textContent = text;
    messageStatusText.textContent = text;
  } else if (status === "disconnected") {
    indicator.classList.add('status-disconnected');
    statusText.textContent = text;
    messageStatusText.textContent = text;
  } else if (status === "connecting") {
    indicator.classList.add('status-connecting');
    statusText.textContent = text;
    messageStatusText.textContent = text;
  }
}

// 生成RSA密钥对
async function generateRSAKeys() {
  return new Promise((resolve) => {
    logToPanel("正在生成RSA密钥对...", "info");
    
    const encrypt = new JSEncrypt({ default_key_size: 2048 });
    encrypt.getKey(() => {
      logToPanel("已生成RSA-2048密钥对", "success");
      resolve({
        privateKey: encrypt.getPrivateKey(),
        publicKey: encrypt.getPublicKey()
      });
    });
  });
}

// 创建新房间
async function createRoom() {
  const agree = document.getElementById('agree-terms').checked;
  if (!agree) {
    logToPanel("请先同意免责协议", "warning");
    alert("请先同意免责协议");
    return;
  }
  
  try {
    // 生成RSA密钥对
    rsaKeys = await generateRSAKeys();
    
    // 创建房间
    const password = document.getElementById('room-password').value;
    logToPanel("正在创建新房间...", "info");
    socket.emit('join_room', {
      public_key: rsaKeys.publicKey,
      password: password
    });
  } catch (e) {
    logToPanel(`创建房间失败: ${e.message}`, "error");
    alert('创建房间失败: ' + e.message);
  }
}

// 加入房间
async function joinRoom() {
  const agree = document.getElementById('agree-terms').checked;
  if (!agree) {
    logToPanel("请先同意免责协议", "warning");
    alert("请先同意免责协议");
    return;
  }
  
  const roomId = document.getElementById('join-room-id').value.trim();
  if (!roomId) {
    logToPanel("请输入房间ID", "warning");
    alert("请输入房间ID");
    return;
  }
  
  try {
    // 生成RSA密钥对
    rsaKeys = await generateRSAKeys();
    
    const password = document.getElementById('room-password').value;
    currentRoomId = roomId;
    document.getElementById('room-id-display').value = currentRoomId;
    
    logToPanel(`正在加入房间 ${roomId}...`, "info");
    socket.emit('join_room', {
      room_id: roomId,
      public_key: rsaKeys.publicKey,
      password: password
    });
  } catch (e) {
    logToPanel(`加入房间失败: ${e.message}`, "error");
    alert('加入房间失败: ' + e.message);
  }
}

// 更新用户列表
function updateUserList(userList) {
  const container = document.getElementById('user-list-container');
  container.innerHTML = '';
  
  const users = userList || Object.entries(userPublicKeys).map(([sid, publicKey]) => ({
    sid: sid,
    public_key: publicKey
  }));
  
  userCount = users.length;
  document.getElementById('user-count').textContent = userCount;
  
  if (users.length === 0) {
    container.innerHTML = `
      <div class="empty-state">
        <i class="fas fa-users-slash"></i>
        <p>暂无在线用户</p>
      </div>
    `;
    return;
  }
  
  users.forEach(user => {
    const userItem = document.createElement('div');
    userItem.className = 'user-item';
    
    const firstChar = getShortId(user.sid).charAt(0).toUpperCase();
    
    userItem.innerHTML = `
      <div class="user-avatar">${firstChar}</div>
      <div class="user-name">
        <div>${getShortId(user.sid)}</div>
        <div class="user-status">${user.sid === currentUserSid ? '我' : '在线'}</div>
      </div>
      <div>
        <span class="badge bg-light text-dark">${user.sid === currentUserSid ? '我' : '其他'}</span>
      </div>
    `;
    container.appendChild(userItem);
  });
}

// 发送消息
function sendMessage() {
  if (!isChatEnabled || !currentRoomId) {
    logToPanel("聊天功能未启用或未加入房间", "warning");
    return;
  }
  
  const input = document.getElementById('message-input');
  const text = input.value.trim();
  if (!text) return;
  
  // 为消息创建数字签名
  let signature = null;
  try {
    const sig = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
    sig.init(rsaKeys.privateKey);
    sig.updateString(text);
    signature = sig.sign();
    logToPanel("消息签名已生成", "success");
  } catch (e) {
    logToPanel(`签名生成失败: ${e.message}`, "error");
  }
  
  // 显示自己的消息
  displayMessage('我', text, new Date().toISOString(), 'me');
  input.value = '';
  
  // 更新消息计数
  messageCount++;
  document.getElementById('message-count').textContent = messageCount;
  
  // 向房间中其他用户发送加密消息和签名
  let sentCount = 0;
  Object.entries(userPublicKeys).forEach(([sid, publicKey]) => {
    if (sid === currentUserSid) return;
    
    try {
      // 使用接收方的公钥加密消息
      const encrypt = new JSEncrypt();
      encrypt.setPublicKey(publicKey);
      const encrypted = encrypt.encrypt(text);
      
      if (!encrypted) {
        logToPanel(`加密给用户 ${getShortId(sid)} 的消息失败`, "error");
        return;
      }
      
      // 发送加密消息和签名
      socket.emit('send_message', {
        room_id: currentRoomId,
        encrypted_message: encrypted,
        signature: signature
      });
      
      sentCount++;
      logToPanel(`消息已发送给用户 ${getShortId(sid)}`, "success");
    } catch (e) {
      logToPanel(`发送消息给用户 ${getShortId(sid)} 时出错: ${e.message}`, "error");
    }
  });
  
  if (sentCount === 0) {
    logToPanel("消息已发送，但当前房间没有其他用户", "warning");
  }
}

// 显示消息
function displayMessage(sender, text, timestamp, type) {
  const messages = document.getElementById('messages');
  
  // 如果还是初始状态，清除占位内容
  if (messages.innerHTML.includes('fa-comment-slash')) {
    messages.innerHTML = '';
  }
  
  const messageDiv = document.createElement('div');
  messageDiv.className = `message-bubble ${type}`;
  
  const time = new Date(timestamp);
  const timeStr = time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  
  messageDiv.innerHTML = `
    <div><strong>${sender}:</strong> ${text}</div>
    <div class="message-time">${timeStr}</div>
  `;
  messages.appendChild(messageDiv);
  messages.scrollTop = messages.scrollHeight;
}

// 显示系统消息
function displaySystemMessage(text) {
  const messages = document.getElementById('messages');
  const messageDiv = document.createElement('div');
  messageDiv.className = 'system-message';
  messageDiv.innerHTML = `<i class="fas fa-info-circle me-1"></i> ${text}`;
  messages.appendChild(messageDiv);
  messages.scrollTop = messages.scrollHeight;
}

// 启用聊天功能
function enableChat() {
  const messageInput = document.getElementById('message-input');
  messageInput.disabled = false;
  messageInput.focus();
  
  const sendButton = document.querySelector('.btn-send');
  sendButton.disabled = false;
  
  isChatEnabled = true;
  displaySystemMessage('您已加入房间，可以开始聊天');
  logToPanel("聊天功能已启用", "success");
}

// 禁用聊天功能
function disableChat() {
  document.getElementById('message-input').disabled = true;
  document.querySelector('.btn-send').disabled = true;
  
  isChatEnabled = false;
  displaySystemMessage('您已离开房间，聊天已禁用');
  logToPanel("聊天功能已禁用", "warning");
  
  // 重置状态
  currentRoomId = null;
  userPublicKeys = {};
  updateUserList();
}

// 生成短ID
function getShortId(id) {
  return id ? id.substring(0, 6) : 'unknown';
}

// 复制房间ID
function copyRoomId() {
  if (!currentRoomId) return;
  const input = document.getElementById('room-id-display');
  input.select();
  document.execCommand('copy');
  logToPanel("房间ID已复制到剪贴板", "success");
  alert('房间ID已复制到剪贴板');
}

// 初始化
document.addEventListener('DOMContentLoaded', () => {
  initSocket();
  
  // 处理消息输入框的Enter键
  document.getElementById('message-input').addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
      sendMessage();
    }
  });
  
  // 初始禁用聊天
  disableChat();
});